from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QSplitter, QToolBar,
    QMessageBox, QInputDialog, QFileDialog
)
from PyQt6.QtGui import QIcon, QColor,QAction
from PyQt6.QtCore import Qt, QSize

from PyQt6.Qsci import (
    QsciScintilla, QsciLexerSQL
)

print("QScintilla for PyQt6 is ready.")

from widgets.result_tab import ResultTab
from core.query_engine import QueryEngine
import re
import pandas as pd


class SQLEditor(QWidget):
    def __init__(self, parent=None, connection_manager=None):
        super().__init__(parent)
        self.connection_manager = connection_manager
        self.query_engine = QueryEngine(connection_manager)

        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # 工具栏
        self.toolbar = QToolBar()
        self.toolbar.setIconSize(QSize(16, 16))
        self.create_toolbar_actions()
        self.layout.addWidget(self.toolbar)

        # 分割器
        self.splitter = QSplitter(Qt.Orientation.Vertical)

        # SQL 编辑器
        self.editor = QsciScintilla(self)
        self.setup_editor()

        # 结果标签页
        self.result_tab = ResultTab()

        self.splitter.addWidget(self.editor)
        self.splitter.addWidget(self.result_tab)
        self.splitter.setSizes([400, 200])

        self.layout.addWidget(self.splitter)

        # 行号随内容更新
        self.editor.textChanged.connect(self.update_line_numbers)

    # ---------- 其余方法保持不变 ----------
    def create_toolbar_actions(self):
        self.run_action = QAction(QIcon("resources/icons/run.png"), "执行 (F5)", self)
        self.run_action.setShortcut("F5")
        self.run_action.triggered.connect(self.execute_query)
        self.toolbar.addAction(self.run_action)

        self.run_current_action = QAction(
            QIcon("resources/icons/run_current.png"),
            "执行当前语句 (Ctrl+Enter)", self
        )
        self.run_current_action.setShortcut("Ctrl+Return")
        self.run_current_action.triggered.connect(self.execute_current_query)
        self.toolbar.addAction(self.run_current_action)

        self.format_action = QAction(
            QIcon("resources/icons/format.png"),
            "格式化 (Ctrl+Shift+F)", self
        )
        self.format_action.setShortcut("Ctrl+Shift+F")
        self.format_action.triggered.connect(self.format_sql)
        self.toolbar.addAction(self.format_action)

        self.toolbar.addSeparator()

        self.comment_action = QAction(
            QIcon("resources/icons/comment.png"),
            "注释/取消注释 (Ctrl+/)", self
        )
        self.comment_action.setShortcut("Ctrl+/")
        self.comment_action.triggered.connect(self.toggle_comment)
        self.toolbar.addAction(self.comment_action)

        self.find_action = QAction(
            QIcon("resources/icons/find.png"),
            "查找替换 (Ctrl+F)", self
        )
        self.find_action.setShortcut("Ctrl+F")
        self.find_action.triggered.connect(self.show_find_dialog)
        self.toolbar.addAction(self.find_action)

        self.toolbar.addSeparator()

        self.save_action = QAction(QIcon("resources/icons/save.png"), "保存 (Ctrl+S)", self)
        self.save_action.setShortcut("Ctrl+S")
        self.save_action.triggered.connect(self.save_sql)
        self.toolbar.addAction(self.save_action)

    def setup_editor(self):
        # 1. 词法高亮
        self.lexer = QsciLexerSQL()
        font = self.editor.font()
        font.setFamily("Consolas")
        font.setPointSize(10)
        self.lexer.setFont(font)
        self.editor.setLexer(self.lexer)

        # 2. 自动补全（全部设置在编辑器上）
        self.editor.setAutoCompletionSource(QsciScintilla.AutoCompletionSource.AcsAll)
        self.editor.setAutoCompletionThreshold(2)
        self.editor.setAutoCompletionUseSingle(
            QsciScintilla.AutoCompletionUseSingle.AcusExplicit
        )
        self.editor.setAutoCompletionCaseSensitivity(False)

        # 3. 基础编辑器配置
        self.editor.setAutoIndent(True)
        self.editor.setIndentationsUseTabs(False)
        self.editor.setTabWidth(4)
        self.editor.setIndentationGuides(True)
        self.editor.setFolding(QsciScintilla.FoldStyle.BoxedTreeFoldStyle)
        self.editor.setBraceMatching(QsciScintilla.BraceMatch.SloppyBraceMatch)

        # 4. 行号边距
        self.editor.setMarginType(0, QsciScintilla.MarginType.NumberMargin)
        self.editor.setMarginWidth(0, "0000")
        self.editor.setMarginsBackgroundColor(QColor("#f0f0f0"))
        self.editor.setMarginsForegroundColor(QColor("#606060"))

        # 5. 当前行高亮
        self.editor.setCaretLineVisible(True)
        self.editor.setCaretLineBackgroundColor(QColor("#ffe4e4"))
        self.editor.setCaretForegroundColor(QColor("#ff0000"))

        self.update_line_numbers()

    def update_line_numbers(self):
        line_count = self.editor.lines()
        self.editor.setMarginWidth(0, f"{line_count + 1}000")

    # ---------- 以下 execute_query / execute_current_query / format_sql / toggle_comment
    # ---------- / show_find_dialog / find_text / save_sql 等方法保持不变 ----------
    def execute_query(self):
        sql = self.editor.text().strip()
        if not sql:
            return
        try:
            results, messages = self.query_engine.execute_query(sql)
            if results and isinstance(results, list) and isinstance(results[0], dict):
                df = pd.DataFrame(results)
                self.result_tab.show_results([df], messages)
                self.last_result_df = df
            else:
                self.result_tab.show_results([], messages)
                self.last_result_df = None
        except Exception as e:
            QMessageBox.critical(self, "执行错误", f"执行SQL时出错:\n{str(e)}")

    def execute_current_query(self):
        cursor = self.editor.getCursorPosition()
        line, index = cursor[0], cursor[1]
        current_text = self.editor.text()
        lines = current_text.split('\n')

        start_line = line
        end_line = line
        while start_line > 0 and not lines[start_line].strip().endswith(';'):
            start_line -= 1
        while end_line < len(lines) - 1 and not lines[end_line].strip().endswith(';'):
            end_line += 1

        current_statement = '\n'.join(lines[start_line:end_line + 1]).strip()
        if not current_statement:
            return
        if current_statement.endswith(';'):
            current_statement = current_statement[:-1]

        try:
            results, messages = self.query_engine.execute_query(current_statement)
            if results and isinstance(results, list) and isinstance(results[0], dict):
                df = pd.DataFrame(results)
                self.result_tab.show_results([df], messages)
                self.last_result_df = df
            else:
                self.result_tab.show_results([], messages)
                self.last_result_df = None
        except Exception as e:
            QMessageBox.critical(self, "执行错误", f"执行SQL时出错:\n{str(e)}")

    def format_sql(self):
        sql = self.editor.text()
        formatted = re.sub(
            r'(?i)\b(SELECT|FROM|WHERE|JOIN|LEFT JOIN|RIGHT JOIN|INNER JOIN|GROUP BY|ORDER BY|HAVING|LIMIT|UNION|INSERT INTO|UPDATE|DELETE FROM|CREATE TABLE|ALTER TABLE|DROP TABLE|VALUES)\b',
            r'\n\1', sql
        )
        lines = formatted.split('\n')
        indent_level = 0
        formatted_lines = []
        for line in lines:
            line = line.strip()
            if not line:
                continue
            if line.upper().startswith(('END', 'ELSE', 'ELSEIF', 'END IF')):
                indent_level = max(0, indent_level - 1)
            formatted_lines.append(' ' * (indent_level * 4) + line)
            if line.upper().startswith(('BEGIN', 'IF', 'ELSE', 'ELSEIF', 'CASE', 'WHEN')):
                indent_level += 1
            elif line.upper().startswith(('END', 'END IF', 'END CASE')):
                indent_level = max(0, indent_level - 1)
        formatted = '\n'.join(formatted_lines)
        self.editor.setText(formatted)

    def toggle_comment(self):
        start_line = self.editor.getSelection()[0]
        end_line = self.editor.getSelection()[2]
        cursor = self.editor.getCursorPosition()
        if start_line == -1:
            start_line = end_line = cursor[0]

        all_commented = all(
            self.editor.text(i).lstrip().startswith('--')
            for i in range(start_line, end_line + 1)
        )

        self.editor.beginUndoAction()
        for i in range(start_line, end_line + 1):
            text = self.editor.text(i)
            if all_commented:
                new = re.sub(r'^\s*--\s?', '', text, 1)
            else:
                new = '-- ' + text
            self.editor.setSelection(i, 0, i, len(text))
            self.editor.replaceSelectedText(new)
        self.editor.endUndoAction()

    def show_find_dialog(self):
        find_text, ok = QInputDialog.getText(self, "查找", "查找内容:")
        if ok and find_text:
            self.find_text(find_text)

    def find_text(self, text):
        line, col = self.editor.getCursorPosition()
        pos = self.editor.positionFromLineIndex(line, col)
        full_text = self.editor.text()
        new_pos = full_text.find(text, pos)
        if new_pos == -1:
            new_pos = full_text.find(text)
        if new_pos != -1:
            line, col = self.editor.lineIndexFromPosition(new_pos)
            self.editor.setSelection(line, col, line, col + len(text))
            self.editor.ensureLineVisible(line)
        else:
            QMessageBox.information(self, "查找", f"未找到 '{text}'")

    def save_sql(self):
        path, _ = QFileDialog.getSaveFileName(
            self, "保存SQL文件", "", "SQL Files (*.sql);;All Files (*)"
        )
        if path:
            try:
                with open(path, 'w', encoding='utf-8') as f:
                    f.write(self.editor.text())
                QMessageBox.information(self, "保存成功", f"文件已保存到:\n{path}")
            except Exception as e:
                QMessageBox.critical(self, "保存错误", f"保存文件时出错:\n{str(e)}")